#include "mysql.hpp"
#include "user.hxx"
#include "user-odb.hxx"

namespace mag {

// UserTable 类提供了对 User 实体的增、删、改、查操作
class UserTable {
    public:
        // 使用智能指针来管理 UserTable 对象
        using ptr = std::shared_ptr<UserTable>;

        // 构造函数，接收一个数据库连接
        UserTable(const std::shared_ptr<odb::core::database> &db):_db(db) {}

        // 插入新用户到数据库
        bool insert(const std::shared_ptr<User> &user) {
            try {
                // 开始事务
                odb::transaction trans(_db->begin());
                // 持久化 User 对象
                _db->persist(*user);
                // 提交事务
                trans.commit();
                LOG_INFO("User {} inserted successfully", user->nickname());
            } catch (std::exception &e) {
                // 处理插入失败的情况
                LOG_ERROR("新增用户失败 {}:{}！", user->nickname(), e.what());
                return false;
            }
            return true;
        }

        // 更新已存在的用户信息
        bool update(const std::shared_ptr<User> &user) {
            try {
                // 开始事务
                odb::transaction trans(_db->begin());
                // 更新 User 对象
                _db->update(*user);
                // 提交事务
                trans.commit();
            } catch (std::exception &e) {
                // 处理更新失败的情况
                LOG_ERROR("更新用户失败 {}:{}！", user->nickname(), e.what());
                return false;
            }
            return true;
        }

        // 根据昵称查询单个用户
        std::shared_ptr<User> select_by_nickname(const std::string &nickname) {
            std::shared_ptr<User> res;
            try {
                // 开始事务
                odb::transaction trans(_db->begin());
                typedef odb::query<User> query;
                typedef odb::result<User> result;
                // 执行查询
                res.reset(_db->query_one<User>(query::nickname == nickname));
                // 提交事务
                trans.commit();
            } catch (std::exception &e) {
                // 处理查询失败的情况
                LOG_ERROR("通过昵称查询用户失败 {}:{}！", nickname, e.what());
            }
            return res;
        }

        // 根据手机号查询单个用户
        std::shared_ptr<User> select_by_phone(const std::string &phone) {
            std::shared_ptr<User> res;
            try {
                // 开始事务
                odb::transaction trans(_db->begin());
                typedef odb::query<User> query;
                typedef odb::result<User> result;
                // 执行查询
                res.reset(_db->query_one<User>(query::phone == phone));
                // 提交事务
                trans.commit();
            } catch (std::exception &e) {
                // 处理查询失败的情况
                LOG_ERROR("通过手机号查询用户失败 {}:{}！", phone, e.what());
            }
            return res;
        }

        // 根据用户ID查询单个用户
        std::shared_ptr<User> select_by_id(const std::string &user_id) {
            std::shared_ptr<User> res;
            try {
                // 开始事务
                odb::transaction trans(_db->begin());
                typedef odb::query<User> query;
                typedef odb::result<User> result;
                // 执行查询
                res.reset(_db->query_one<User>(query::user_id == user_id));
                // 提交事务
                trans.commit();
            } catch (std::exception &e) {
                // 处理查询失败的情况
                LOG_ERROR("通过用户ID查询用户失败 {}:{}！", user_id, e.what());
            }
            return res;
        }

        // 根据一组用户ID批量查询用户
        std::vector<User> select_multi_users(const std::vector<std::string> &id_list) {
            if (id_list.empty()) {
                return std::vector<User>();  // 如果 ID 列表为空，直接返回空的结果
            }
            std::vector<User> res;
            try {
                // 开始事务
                odb::transaction trans(_db->begin());
                typedef odb::query<User> query;
                typedef odb::result<User> result;

                // 构建查询条件：user_id IN ('id1', 'id2', ...)
                std::stringstream ss;
                ss << "user_id in (";
                for (const auto &id : id_list) {
                    ss << "'" << id << "',";
                }
                std::string condition = ss.str();
                condition.pop_back();  // 去除最后一个多余的逗号
                condition += ")";
                
                // 执行查询
                result r(_db->query<User>(condition));
                for (result::iterator i(r.begin()); i != r.end(); ++i) {
                    res.push_back(*i);  // 将查询结果加入到结果集
                }
                // 提交事务
                trans.commit();
            } catch (std::exception &e) {
                // 处理查询失败的情况
                LOG_ERROR("通过用户ID批量查询用户失败:{}！", e.what());
            }
            return res;
        }

    private:
        // 数据库连接对象，指向 ODB 的数据库实例
        std::shared_ptr<odb::core::database> _db;
};

}
